<?php

namespace app\admin\controller\vip;

use app\admin\library\Auth;
use app\api\model\MemberVipCard;
use app\job\Export;
use ba\Exception;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\facade\Db;
use think\facade\Queue;
use Throwable;
use app\common\controller\Backend;

/**
 * 卡密管理
 */
class Code extends Backend
{
    /**
     * Code模型对象
     * @var object
     * @phpstan-var \app\admin\model\vip\Code
     */
    protected object $model;

    protected array|string $preExcludeFields = ['id', 'create_time', 'update_time'];

    protected array $withJoinTable = ['admin', 'vipCard'];

    protected string|array $quickSearchField = ['id'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\admin\model\vip\Code();
    }

    /**
     * 查看
     * @throws Throwable
     */
    public function index(): void
    {
        // 如果是 select 则转发到 select 方法，若未重写该方法，其实还是继续执行 index
        if ($this->request->param('select')) {
            $this->select();
        }

        /**
         * 1. withJoin 不可使用 alias 方法设置表别名，别名将自动使用关联模型名称（小写下划线命名规则）
         * 2. 以下的别名设置了主表别名，同时便于拼接查询参数等
         * 3. paginate 数据集可使用链式操作 each(function($item, $key) {}) 遍历处理
         */
        list($where, $alias, $limit, $order) = $this->queryBuilder();
        $map = [];
        $user_id = $this->auth->id;
        $group_id = array_column($this->auth->getGroups($this->auth->id), 'group_id');
        if (in_array(5, $group_id)) {
            $map[] = ['admin_id', '=', $user_id];
        }
        $res = $this->model
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->alias($alias)
            ->where($where)
            ->where($map)
            ->order($order)
            ->paginate($limit);
        $res->visible(['admin' => ['nickname'], 'vipCard' => ['name', 'type']]);


        $this->success('', [
            'list' => $res->items(),
            'total' => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }


    /**
     * 添加
     */
    public function add(): void
    {
        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }

            $data = $this->excludeFields($data);
            if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                $data[$this->dataLimitField] = $this->auth->id;
            }

            $result = false;
            $this->model->startTrans();
            try {
                // 模型验证
                if ($this->modelValidate) {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    if (class_exists($validate)) {
                        $validate = new $validate();
                        if ($this->modelSceneValidate) {
                            $validate->scene('add');
                        }
                        $validate->check($data);
                    }
                }

                //查询现在的卡号
                $last = $this->model->order('id desc')->find();
                $last_key = $last['id'] ?? 2001;
                $res = [];
                for ($i = 0; $i < $data['number']; $i++) {
                    $last_key++;
                    $res[] = [
                        'id' => $last_key,
                        'admin_id' => $data['admin_id'],
                        'vip_card_id' => $data['vip_card_id'],
                        'number' => $data['prefix'] . $last_key,
                        'password' => mt_rand(100000, 999999),
                        'status' => 0,
                        'user_expire_time' => strtotime($data['user_expire_time']),
                        'create_time' => time(),
                        'update_time' => time(),
                    ];
                }
                $result = $this->model->insertAll($res);
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Added successfully'));
            } else {
                $this->error(__('No rows were added'));
            }
        }

        $this->error(__('Parameter error'));
    }


    public function freeze()
    {
        $data = $this->request->post();
        if (!$data) {
            $this->error('请选择冻结项');
        }
        $result = $this->model->where(['id' => $data['ids']])->update(['is_freeze' => 1, 'reason' => $data['reason']]);
        if ($result) {
            $this->success('操作成功');
        } else {
            $this->error('操作失败');
        }
    }


    public function batchTransfer()
    {
        $data = $this->request->post();
        $start = $data['start'] ?? '';
        $end = $data['end'] ?? '';
        if (!$start || !$end) {
            $this->error('其实和结束不能为空');
        }
        $where[] = ['id', '>=', $start];
        $where[] = ['id', '<=', $end];

        $code = (new \app\admin\model\vip\Code())->where($where)->select()->toArray();
        if (!$code) {
            $this->error('没有数据');
        }
        $code_ids = array_column($code, 'id');
        $vip_code = array_column($code, 'number');
        try {
            Db::startTrans();
            $res = (new \app\admin\model\vip\Code())->where(['id' => $code_ids])->update(
                ['admin_id' => $data['admin_id']]
            );
            //更新激活
            (new MemberVipCard())->where(['vip_code' => $vip_code])->update(['admin_id' => $data['admin_id']]);
            //酒店更新订单
            (new \app\admin\model\hotel\Order())->where(['code_number' => $vip_code])->update(
                ['admin_id' => $data['admin_id']]
            );
            //更新景区订单
            (new \app\admin\model\scenic\Order())->where(['code_number' => $vip_code])->update(
                ['admin_id' => $data['admin_id']]
            );

            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('转拨成功');
    }


    public function unhitch()
    {
        $data = $this->request->post();
        if (!$data) {
            $this->error('请选择冻结项');
        }
        $result = $this->model->where(['id' => $data['ids']])->update(['is_freeze' => 0, 'reason' => null]);
        if ($result) {
            $this->success('操作成功');
        } else {
            $this->error('操作失败');
        }
    }


    /**
     * 创建订单导出任务
     * @return void
     */
    public function addExportTask(): void
    {
        $params = $this->request->param();

        $this->model->startTrans();
        try {
            // 模型验证
            if ($this->modelValidate) {
                $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                if (class_exists($validate)) {
                    $validate = new $validate;
                    if ($this->modelSceneValidate) {
                        $validate->scene('export');
                    }
                    $validate->check($params);
                }
            }
            list($where, $alias, $limit, $order) = $this->queryBuilder();
            $data['query_params'] = json_encode([
                'where' => $where,
                'alias' => $alias,
                'order' => $order,
                'withJoinTable' => $this->withJoinTable,
                'withJoinType' => $this->withJoinType,
            ]);
            $data['admin_id'] = Auth::instance()->getAdmin()->id;
            $data['name'] = "卡密导出".date('YmdHis').'.xlsx';
            $data['type'] = 1;

            $exportTask = \app\admin\model\Export::create($data);
            $data = ['id' => $exportTask->id];
            Queue::push(Export::class,$data , Export::$queue);
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->error($e->getMessage() ?: __('导出任务创建失败'), ['err' => $e->getMessage()]);
        }

        $this->success(__('导出任务创建成功'));
    }



    /**
     * 获取表头字段
     * @return void
     */
    public function getTableHeadField(): void
    {
        $this->success('', $this->orderExportService->orderExportField());
    }


    /**
     * 若需重写查看、编辑、删除等方法，请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
     */
}
